home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / src / MGL / mglmesa.c < prev    next >
C/C++ Source or Header  |  1999-02-04  |  45KB  |  1,224 lines

  1. /****************************************************************************
  2. *
  3. *                        Mesa bindings for SciTech MGL
  4. *
  5. * Language:        ANSI C
  6. * Environment:    Any
  7. *
  8. * Description:    Main Mesa 3D library interface between the MGL and
  9. *               Mesa. For maximum peformance we call the MGL's internal
  10. *                rendering functions directly so we can bypass all the
  11. *                clipping and regular MGL API stuff as all that is already
  12. *                handled by Mesa before the calls get here.
  13. *
  14. *                Note also that all rendering is inherently single threaded
  15. *                so we optimize for this case by using a global current
  16. *                context structure.
  17. *
  18. *                This module contains generic interface routines.
  19. *
  20. * This library is free software; you can redistribute it and/or
  21. * modify it under the terms of the GNU Library General Public
  22. * License as published by the Free Software Foundation; either
  23. * version 2 of the License, or (at your option) any later version.
  24. *
  25. * This library is distributed in the hope that it will be useful,
  26. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  27. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  28. * Library General Public License for more details.
  29. *
  30. * You should have received a copy of the GNU Library General Public
  31. * License along with this library; if not, write to the Free
  32. * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  33. *
  34. ****************************************************************************/
  35.  
  36. #include "mgl/mmesap.h"
  37. #pragma hdrstop
  38. #include "GL/mglmesa.h"
  39. #include <string.h>
  40. #include <stdlib.h>
  41.  
  42. /*--------------------------- Global Variables ----------------------------*/
  43.  
  44. #ifdef    __WINDOWS__
  45. MGLCallbacks    _MGL_callbacks;            /* MGL callback functions        */
  46. #endif
  47. gmode_t            _MGL_mi;                /* MGL mode information            */
  48. pixel_format_t    _MGL_pf;                /* MGL mode pixel format        */
  49. vecs            _MGL_vecs;                /* MGL Rendering vectors         */
  50. MGLRC            _MM_rc;                       /* Current rendering context    */
  51. MGLRC            *_MM_rcPtr = NULL;        /* Pointer to current context    */
  52.  
  53. /*------------------------- Implementation --------------------------------*/
  54.  
  55. #pragma warn -par
  56.  
  57. /**********************************************************************/
  58. /*****              Miscellaneous device driver funcs             *****/
  59. /**********************************************************************/
  60.  
  61. static void begin(GLcontext *ctx,GLenum mode)
  62. /****************************************************************************
  63. *
  64. * Function:        begin
  65. *
  66. * Description:    Called when glBegin is called. We use this oportunity to
  67. *                enable direct framebuffer access for our rendering functions.
  68. *
  69. ****************************************************************************/
  70. {
  71. //     TODO: Call begin directAccess depending on the currently selected mode
  72. //          and also the current rendering attributes (to determine if we need
  73. //          to directly access the buffer. We need this to support VBE/AF.
  74. //
  75. //          We should optimize this to have this code in here run fast, and
  76. //          put the complicated code into the setup_DD_funcs to avoid the
  77. //          overheads of checking in here.
  78.  
  79.     _MGL_vecs.beginDirectAccess();
  80. }
  81.  
  82. static void end(GLcontext *ctx)
  83. /****************************************************************************
  84. *
  85. * Function:        end
  86. *
  87. * Description:    Called when glEnd is called. We use this oportunity to
  88. *                disable direct framebuffer access for our rendering
  89. *                functions.
  90. *
  91. ****************************************************************************/
  92. {
  93.     _MGL_vecs.endDirectAccess();
  94. }
  95.  
  96. static void finish(GLcontext *ctx)
  97. /****************************************************************************
  98. *
  99. * Function:        finish
  100. *
  101. * Description:    Called when glFinish is called. We simply do nothing here.
  102. *
  103. ****************************************************************************/
  104. {
  105. }
  106.  
  107. static void flush(GLcontext *ctx)
  108. /****************************************************************************
  109. *
  110. * Function:        flush
  111. *
  112. * Description:    Called when glFlush is called. We simply do nothing here
  113. *
  114. ****************************************************************************/
  115. {
  116. }
  117.  
  118. static void clear_index(GLcontext *ctx, GLuint index)
  119. /****************************************************************************
  120. *
  121. * Function:        clear_index
  122. * Parameters:    index    - New color index for buffer clears
  123. *
  124. * Description:    Sets the current buffer clear color for color index buffers.
  125. *
  126. ****************************************************************************/
  127. {
  128.     RC.clearColor = index;
  129. }
  130.  
  131. static void clear_color(GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a)
  132. /****************************************************************************
  133. *
  134. * Function:        clear_color
  135. * Parameters:    r,g,b,a    - New RGBA color values for buffer clears
  136. *
  137. * Description:    Set the current buffer clear color for TrueColor buffers.
  138. *                Note that Mesa passes us color values pre-scaled to the
  139. *                proper number of color bits:
  140. *
  141. *                    [0,ctx->Visual->RedScale]
  142. *                    [0,ctx->Visual->GreenScale]
  143. *                    [0,ctx->Visual->BlueScale]
  144. *                    [0,ctx->Visual->AlphaScale]
  145. *
  146. ****************************************************************************/
  147. {
  148.     RC.clearColor = MGL_packColorFast(&PF,r,g,b);
  149. }
  150.  
  151. static GLbitfield clear(GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x,
  152.     GLint y, GLint width, GLint height)
  153. /****************************************************************************
  154. *
  155. * Function:        clear
  156. * Parameters:    all                    - True to clear entire buffer
  157. *                x,y,width,height    - Rectangle to clear
  158. *
  159. * Description:    Clears the buffer in the current clear color
  160. *
  161. ****************************************************************************/
  162. {
  163.        if (mask & GL_COLOR_BUFFER_BIT) {
  164.         VECS.setColor(RC.clearColor);
  165.         if (all)
  166.             VECS.solid.fillRect(0,0,MI.xRes+1,MI.yRes+1);
  167.         else
  168.             VECS.solid.fillRect(x,y,x+width,y+height);
  169.         }
  170.     return mask & (~GL_COLOR_BUFFER_BIT);
  171. }
  172.  
  173. static void set_index(GLcontext *ctx, GLuint index)
  174. /****************************************************************************
  175. *
  176. * Function:        clear_index
  177. * Parameters:    index    - New color index
  178. *
  179. * Description:    Sets the current solid color for color index buffers.
  180. *
  181. ****************************************************************************/
  182. {
  183.     RC.color = index;
  184. }
  185.  
  186. static void set_color(GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a)
  187. /****************************************************************************
  188. *
  189. * Function:        set_color
  190. * Parameters:    r,g,b,a    - New RGBA color value
  191. *
  192. * Description:    Set the current solid color for TrueColor buffers.
  193. *                Note that Mesa passes us color values pre-scaled to the
  194. *                proper number of color bits:
  195. *
  196. *                    [0,ctx->Visual->RedScale]
  197. *                    [0,ctx->Visual->GreenScale]
  198. *                    [0,ctx->Visual->BlueScale]
  199. *                    [0,ctx->Visual->AlphaScale]
  200. *
  201. ****************************************************************************/
  202. {
  203.     RC.color = MGL_packColorFast(&PF,r,g,b);
  204.     RC.red = r;
  205.     RC.green = g;
  206.     RC.blue = b;
  207. }
  208.  
  209. static GLboolean index_mask(GLcontext *ctx, GLuint mask)
  210. /****************************************************************************
  211. *
  212. * Function:        index_mask
  213. * Parameters:    mask    - Color index mask
  214. * Returns:        True if we implement masking, false if not
  215. *
  216. * Description:    Implements color index masking ala glIndexMask if possible.
  217. *                We currently return false for this function.
  218. *
  219. ****************************************************************************/
  220. {
  221.     return GL_FALSE;
  222. }
  223.  
  224. static GLboolean color_mask(GLcontext *ctx,
  225.     GLboolean rmask, GLboolean gmask,GLboolean bmask, GLboolean amask)
  226. /****************************************************************************
  227. *
  228. * Function:        color_mask
  229. * Parameters:    rmask    - Red mask
  230. *                gmask    - Green mask
  231. *                bmask    - Blue mask
  232. *                amask    - Alpha mask
  233. * Returns:        True if we implement masking, false if not
  234. *
  235. * Description:    Implements RGB color masking ala glColorMask if possible.
  236. *                We currently return false for this function.
  237. *
  238. ****************************************************************************/
  239. {
  240.     return GL_FALSE;
  241. }
  242.  
  243. static GLboolean logicop(GLcontext *ctx, GLenum op)
  244. /****************************************************************************
  245. *
  246. * Function:        logicop
  247. * Parameters:    op    - New logic op to enable
  248. * Returns:        True if we implement masking, false if not
  249. *
  250. * Description:    Implements logic operations ala glLogicOp if possible. For
  251. *                op's that we dont support we simply return GL_FALSE and it
  252. *                is implemented in software by Mesa.
  253. *
  254. ****************************************************************************/
  255. {
  256. #if 0
  257.     int    mode;
  258.  
  259.     switch (op) {
  260.         case GL_COPY:    mode = MGL_REPLACE_MODE;    break;
  261.         case GL_AND:    mode = MGL_AND_MODE;        break;
  262.         case GL_OR:        mode = MGL_OR_MODE;            break;
  263.         case GL_XOR:    mode = MGL_XOR_MODE;        break;
  264.         default:          return GL_FALSE;
  265.         }
  266.     DC.r.setWriteMode(mode);
  267.     return GL_TRUE;
  268. #else
  269.     return GL_FALSE;
  270. #endif
  271. }
  272.  
  273. static void dither(GLcontext *ctx, GLboolean enable)
  274. /****************************************************************************
  275. *
  276. * Function:        dither
  277. * Parameters:    enable    - True to enable dithering, false to disable it 
  278. *
  279. * Description:    Enables dithering mode if applicable. 
  280. *
  281. ****************************************************************************/
  282. {
  283.     if (enable) 
  284.         RC.pixelformat = RC.dithered_pf;
  285.     else
  286.         RC.pixelformat = RC.undithered_pf;
  287.     setup_DD_pointers(ctx);
  288. }
  289.  
  290. static GLboolean set_buffer(GLcontext *ctx, GLenum mode)
  291. /****************************************************************************
  292. *
  293. * Function:        set_buffer
  294. * Parameters:    mode    - Buffer mode to enable 
  295. *
  296. * Description:    Sets the buffer access mode to the front buffer or the
  297. *                back buffer for the application. The MGL always allows
  298. *                direct access to both buffers in double buffered fullscreen
  299. *                modes, but when rendering to a memory device context (ie:
  300. *                when rendering in a window in the windows environment) we
  301. *                only have a single buffer available.
  302. *
  303. ****************************************************************************/
  304. {
  305.     if (!RC.gl_vis->DBflag) {
  306.         MGL_makeCurrentDC(RC.dc);
  307.         return (mode = GL_FRONT);
  308.         }
  309.     if (RC.dc->mi.maxPage > 0) {
  310.         /* Hardware page flipping */
  311.         if (mode == GL_FRONT)
  312.             MGL_setActivePage(RC.dc,RC.frontbuffer);
  313.         else if (mode == GL_BACK)
  314.             MGL_setActivePage(RC.dc,RC.backbuffer);
  315.         else
  316.             return GL_FALSE;
  317.         }
  318.     if (RC.memdc) {
  319.         /* Software double buffering using a memory DC. In some cases
  320.          * we may not be able to access the display memory surface for the
  321.          * front buffer in which case this will fail.
  322.          */
  323.         if (mode == GL_FRONT && (MGL_surfaceAccessType(RC.dc) != MGL_NO_ACCESS)) 
  324.             MGL_makeCurrentDC(RC.dc);
  325.         else if (mode == GL_BACK)
  326.             MGL_makeCurrentDC(RC.memdc);
  327.         else
  328.             return GL_FALSE;
  329.         }
  330.     else {
  331.         /* Hardware page flipping only */
  332.         MGL_makeCurrentDC(RC.dc);
  333.         }
  334.     RC.bufferMode = mode;
  335.     setup_DD_pointers(ctx);
  336.     return GL_TRUE;
  337. }
  338.  
  339. static void get_buffer_size(GLcontext *ctx, GLuint *width, GLuint *height)
  340. /****************************************************************************
  341. *
  342. * Function:        get_buffer_size
  343. * Parameters:    width    - Place to store buffer width
  344. *                height    - Place to store buffer height 
  345. *
  346. * Description:    Returns the current buffer width and height. We simply
  347. *                return the currently active device context's width and
  348. *                height, which will change if the buffer is resized in a
  349. *                windowed environment.
  350. *
  351. ****************************************************************************/
  352. {
  353.     if (MI.xRes != RC.dispdc->mi.xRes || MI.yRes != RC.dispdc->mi.yRes) {
  354.         MI.xRes = RC.dispdc->mi.xRes;
  355.         MI.yRes = RC.dispdc->mi.yRes;
  356.  
  357.         /* Resize our system memory back buffer if we have one */
  358.         if (RC.memdc) {
  359.             MGL_destroyDC(RC.memdc);
  360.             RC.memdc = MGL_createMemoryDC(MI.xRes+1,MI.yRes+1,MI.bitsPerPixel,&PF);
  361.             if (!RC.memdc)
  362.                 exit(1);
  363.             RC.dc = RC.memdc;
  364.             if (RC.dispdc->mi.bitsPerPixel == 8) {
  365.                 palette_t pal[256];
  366.                 MGL_getPalette(RC.dispdc,pal,256,0);
  367.                 MGL_setPalette(RC.memdc,pal,256,0);
  368.                 MGL_realizePalette(RC.memdc,256,0,-1);
  369.                 }
  370.             MI = RC.dc->mi;
  371.             }
  372.         }
  373.     *width = MI.xRes+1;
  374.     *height = MI.yRes+1;
  375.     RC.bottom = MI.yRes;
  376. }
  377.  
  378. /**********************************************************************/
  379. /***                    Point rendering                             ***/
  380. /**********************************************************************/
  381.  
  382. PUBLIC points_func mmesa_get_points_func(GLcontext *ctx)
  383. /****************************************************************************
  384. *
  385. * Function:        mmesa_get_points_func
  386. * Parameters:    ctx    - Context to examine
  387. *
  388. * Description:    Analyze context state to see if we can provide a fast points
  389. *                drawing function, like those in points.c.  Otherwise, return
  390. *                NULL.
  391. *
  392. ****************************************************************************/
  393. {
  394. #if 0
  395.     if (ctx->Point.Size == 1.0F && !ctx->Point.SmoothFlag && ctx->RasterMask == 0
  396.             && !ctx->Texture.Enabled) {
  397.         return draw_points;
  398.         }
  399. #endif
  400.     return NULL;
  401. }
  402.  
  403. /**********************************************************************/
  404. /***                      Line rendering                            ***/
  405. /**********************************************************************/
  406.  
  407. PUBLIC line_func mmesa_get_line_func(GLcontext *ctx)
  408. /****************************************************************************
  409. *
  410. * Function:        mmesa_get_line_func
  411. * Parameters:    ctx    - Context to examine
  412. *
  413. * Description:    Analyze context state to see if we can provide a fast line
  414. *                drawing function, like those in lines.c.  Otherwise, return
  415. *                NULL.    
  416. *
  417. ****************************************************************************/
  418. {
  419. #if 0
  420.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  421.    int depth = xmesa->xm_visual->visinfo->depth;
  422.  
  423.    if (ctx->Line.SmoothFlag)              return NULL;
  424.    if (ctx->Texture.Enabled)              return NULL;
  425.    if (ctx->Light.ShadeModel!=GL_FLAT)    return NULL;
  426.  
  427.    if (xmesa->xm_buffer->buffer==XIMAGE
  428.        && ctx->RasterMask==DEPTH_BIT
  429.        && ctx->Depth.Func==GL_LESS
  430.        && ctx->Depth.Mask==GL_TRUE
  431.        && ctx->Line.Width==1.0F
  432.        && ctx->Line.StippleFlag==GL_FALSE) {
  433.       switch (xmesa->pixelformat) {
  434.          case PF_TRUECOLOR:
  435.             return flat_TRUECOLOR_z_line;
  436.          case PF_8A8B8G8R:
  437.             return flat_8A8B8G8R_z_line;
  438.          case PF_8R8G8B:
  439.             return flat_8R8G8B_z_line;
  440.          case PF_5R6G5B:
  441.             return flat_5R6G5B_z_line;
  442.          case PF_DITHER:
  443.             return (depth==8) ? flat_DITHER8_z_line : NULL;
  444.          case PF_LOOKUP:
  445.             return (depth==8) ? flat_LOOKUP8_z_line : NULL;
  446.          case PF_HPCR:
  447.             return flat_HPCR_z_line;
  448.          default:
  449.             return NULL;
  450.       }
  451.    }
  452.    if (xmesa->xm_buffer->buffer==XIMAGE
  453.        && ctx->RasterMask==0
  454.        && ctx->Line.Width==1.0F
  455.        && ctx->Line.StippleFlag==GL_FALSE) {
  456.       switch (xmesa->pixelformat) {
  457.          case PF_TRUECOLOR:
  458.             return flat_TRUECOLOR_line;
  459.          case PF_8A8B8G8R:
  460.             return flat_8A8B8G8R_line;
  461.          case PF_8R8G8B:
  462.             return flat_8R8G8B_line;
  463.          case PF_5R6G5B:
  464.             return flat_5R6G5B_line;
  465.          case PF_DITHER:
  466.             return (depth==8) ? flat_DITHER8_line : NULL;
  467.          case PF_LOOKUP:
  468.             return (depth==8) ? flat_LOOKUP8_line : NULL;
  469.          case PF_HPCR:
  470.             return flat_HPCR_line;
  471.      default:
  472.         return NULL;
  473.       }
  474.    }
  475.    if (xmesa->xm_buffer->buffer!=XIMAGE && ctx->RasterMask==0) {
  476.       setup_x_line_options( ctx );
  477.       return flat_pixmap_line;
  478.    }
  479. #endif
  480.     return NULL;
  481. }
  482.  
  483. /**********************************************************************/
  484. /***                   Triangle rendering                            ***/
  485. /**********************************************************************/
  486.  
  487. triangle_func mmesa_get_triangle_func(GLcontext *ctx)
  488. {
  489. #if 0
  490.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  491.    int depth = xmesa->xm_visual->visinfo->depth;
  492.  
  493.    if (ctx->Polygon.SmoothFlag)     return NULL;
  494.    if (ctx->Texture.Enabled)        return NULL;
  495.  
  496.    if (xmesa->xm_buffer->buffer==XIMAGE) {
  497.       if (   ctx->Light.ShadeModel==GL_SMOOTH
  498.           && ctx->RasterMask==DEPTH_BIT
  499.           && ctx->Depth.Func==GL_LESS
  500.           && ctx->Depth.Mask==GL_TRUE
  501.           && ctx->Polygon.StippleFlag==GL_FALSE) {
  502.          switch (xmesa->pixelformat) {
  503.             case PF_TRUECOLOR:
  504.            return smooth_TRUECOLOR_z_triangle;
  505.             case PF_8A8B8G8R:
  506.                return smooth_8A8B8G8R_z_triangle;
  507.             case PF_8R8G8B:
  508.                return smooth_8R8G8B_z_triangle;
  509.             case PF_5R6G5B:
  510.                return smooth_5R6G5B_z_triangle;
  511.             case PF_HPCR:
  512.            return smooth_HPCR_z_triangle;
  513.             case PF_DITHER:
  514.                return (depth==8) ? smooth_DITHER8_z_triangle
  515.                                         : smooth_DITHER_z_triangle;
  516.             case PF_LOOKUP:
  517.                return (depth==8) ? smooth_LOOKUP8_z_triangle : NULL;
  518.             default:
  519.                return NULL;
  520.          }
  521.       }
  522.       if (   ctx->Light.ShadeModel==GL_FLAT
  523.           && ctx->RasterMask==DEPTH_BIT
  524.           && ctx->Depth.Func==GL_LESS
  525.           && ctx->Depth.Mask==GL_TRUE
  526.           && ctx->Polygon.StippleFlag==GL_FALSE) {
  527.          switch (xmesa->pixelformat) {
  528.             case PF_TRUECOLOR:
  529.            return flat_TRUECOLOR_z_triangle;
  530.             case PF_8A8B8G8R:
  531.                return flat_8A8B8G8R_z_triangle;
  532.             case PF_8R8G8B:
  533.                return flat_8R8G8B_z_triangle;
  534.             case PF_5R6G5B:
  535.                return flat_5R6G5B_z_triangle;
  536.             case PF_HPCR:
  537.            return flat_HPCR_z_triangle;
  538.             case PF_DITHER:
  539.                return (depth==8) ? flat_DITHER8_z_triangle
  540.                                         : flat_DITHER_z_triangle;
  541.             case PF_LOOKUP:
  542.                return (depth==8) ? flat_LOOKUP8_z_triangle : NULL;
  543.             default:
  544.                return NULL;
  545.          }
  546.       }
  547.       if (   ctx->RasterMask==0   /* no depth test */
  548.           && ctx->Light.ShadeModel==GL_SMOOTH
  549.           && ctx->Polygon.StippleFlag==GL_FALSE) {
  550.          switch (xmesa->pixelformat) {
  551.             case PF_TRUECOLOR:
  552.            return smooth_TRUECOLOR_triangle;
  553.             case PF_8A8B8G8R:
  554.                return smooth_8A8B8G8R_triangle;
  555.             case PF_8R8G8B:
  556.                return smooth_8R8G8B_triangle;
  557.             case PF_5R6G5B:
  558.                return smooth_5R6G5B_triangle;
  559.             case PF_HPCR:
  560.            return smooth_HPCR_triangle;
  561.             case PF_DITHER:
  562.                return (depth==8) ? smooth_DITHER8_triangle
  563.                                         : smooth_DITHER_triangle;
  564.             case PF_LOOKUP:
  565.                return (depth==8) ? smooth_LOOKUP8_triangle : NULL;
  566.             default:
  567.                return NULL;
  568.          }
  569.       }
  570.  
  571.       if (   ctx->RasterMask==0   /* no depth test */
  572.           && ctx->Light.ShadeModel==GL_FLAT
  573.           && ctx->Polygon.StippleFlag==GL_FALSE) {
  574.          switch (xmesa->pixelformat) {
  575.             case PF_TRUECOLOR:
  576.            return flat_TRUECOLOR_triangle;
  577.             case PF_8A8B8G8R:
  578.                return flat_8A8B8G8R_triangle;
  579.             case PF_8R8G8B:
  580.                return flat_8R8G8B_triangle;
  581.             case PF_5R6G5B:
  582.                return flat_5R6G5B_triangle;
  583.             case PF_HPCR:
  584.            return flat_HPCR_triangle;
  585.             case PF_DITHER:
  586.                return (depth==8) ? flat_DITHER8_triangle
  587.                                         : flat_DITHER_triangle;
  588.             case PF_LOOKUP:
  589.                return (depth==8) ? flat_LOOKUP8_triangle : NULL;
  590.             default:
  591.                return NULL;
  592.          }
  593.       }
  594.  
  595.       return NULL;
  596.    }
  597.    else {
  598.       /* pixmap */
  599.       if (ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0) {
  600.          setup_x_polygon_options( ctx );
  601.          return flat_pixmap_triangle;
  602.       }
  603.       return NULL;
  604.    }
  605. #endif
  606.     return NULL;
  607. }
  608.  
  609. /**********************************************************************/
  610. /***                      Quad rendering                            ***/
  611. /**********************************************************************/
  612.  
  613. quad_func mmesa_get_quad_func(GLcontext *ctx)
  614. {
  615.     return NULL;
  616. }
  617.  
  618. /**********************************************************************/
  619. /***                   2D Rectangle Rendering                       ***/
  620. /**********************************************************************/
  621.  
  622. rect_func mmesa_get_rect_func(GLcontext *ctx)
  623. {
  624.     return NULL;
  625. }
  626.  
  627. /**********************************************************************/
  628. /*****                 Miscellaneous functions                    *****/
  629. /**********************************************************************/
  630.  
  631. static const char *renderer_string(void)
  632. {
  633.    return "SciTech MGL " MGL_VERSION_STR;
  634. }
  635.  
  636. static void setup_DD_pointers(GLcontext *ctx)
  637. /****************************************************************************
  638. *
  639. * Function:        setup_DD_pointer
  640. * Parameters:    ctx    - Device context to setup pointers for
  641. *
  642. * Description:    Sets up all the device driver rendering pointers for the
  643. *                current rendering state. This function is where we swap in
  644. *                high performance rendering functions when the rendering
  645. *                state allows this.
  646. *
  647. ****************************************************************************/
  648. {
  649.     ibool    doDither = false;
  650.  
  651.     /* Mandatory functions that are always the same */
  652.        ctx->Driver.RendererString = renderer_string;
  653.     ctx->Driver.UpdateState = setup_DD_pointers;
  654.     ctx->Driver.ClearIndex = clear_index;
  655.     ctx->Driver.ClearColor = clear_color;
  656.     ctx->Driver.Clear = clear;
  657.     ctx->Driver.Index = set_index;
  658.     ctx->Driver.Color = set_color;
  659.     ctx->Driver.SetBuffer = set_buffer;
  660.     ctx->Driver.GetBufferSize = get_buffer_size;
  661.  
  662.     /* Driver functions that are always the same */
  663.     ctx->Driver.Begin = begin;
  664.     ctx->Driver.End = end;
  665.     ctx->Driver.Flush = flush;
  666.        ctx->Driver.Finish = finish;
  667.     ctx->Driver.IndexMask = index_mask;
  668.     ctx->Driver.ColorMask = color_mask;
  669.     ctx->Driver.LogicOp = logicop;
  670.     ctx->Driver.Dither = dither;
  671.  
  672.     /* Accelerated point, line and triangle functions */
  673.     ctx->Driver.PointsFunc = mmesa_get_points_func(ctx);
  674.     ctx->Driver.LineFunc = mmesa_get_line_func(ctx);
  675.     ctx->Driver.TriangleFunc = mmesa_get_triangle_func(ctx);
  676.     ctx->Driver.QuadFunc = mmesa_get_quad_func(ctx);
  677.     ctx->Driver.RectFunc = mmesa_get_rect_func(ctx);
  678.  
  679.     /* Accelerated bitmap drawing functions */
  680. #if 0
  681.     ctx->Driver.DrawPixels = draw_pixels;
  682.     ctx->Driver.Bitmap = draw_bitmap;
  683. #endif
  684.  
  685.     /* Optimized pixel span reading/writing functions. Note that we use
  686.      * a (void*) cast as we have removed the 'const'ness of the parameters
  687.      * passed to these functions so we can use the pointers to step through
  688.      * our arrays efficiently.
  689.      */
  690.     switch (RC.pixelformat) {
  691.         case PF_INDEX:
  692.             ctx->Driver.WriteCI32Span           = (void*)(void*)_mmesa_write_span_ci;
  693.             ctx->Driver.WriteCI8Span               = (void*)_mmesa_write_span_ci8;
  694.             ctx->Driver.WriteMonoCISpan           = (void*)_mmesa_write_span_mono_ci;
  695.             ctx->Driver.WriteCI32Pixels         = (void*)_mmesa_write_pixels_ci;
  696.             ctx->Driver.WriteMonoCIPixels         = (void*)_mmesa_write_pixels_mono_ci;
  697.             ctx->Driver.ReadCI32Span              = (void*)_mmesa_read_span_ci;
  698.             ctx->Driver.ReadCI32Pixels              = (void*)_mmesa_read_pixels_ci;
  699.             break;
  700.         case PF_RGB8:
  701.             ctx->Driver.WriteRGBASpan           = (void*)_mmesa_write_span_8_8;
  702.             ctx->Driver.WriteRGBSpan               = (void*)_mmesa_write_span_rgb_8_8;
  703.             ctx->Driver.WriteMonoRGBASpan       = (void*)_mmesa_write_span_mono_8;
  704.             ctx->Driver.WriteRGBAPixels         = (void*)_mmesa_write_pixels_8_8;
  705.             ctx->Driver.WriteMonoRGBAPixels     = (void*)_mmesa_write_pixels_mono_8;
  706.             ctx->Driver.ReadRGBASpan              = (void*)_mmesa_read_span_8_8;
  707.             ctx->Driver.ReadRGBAPixels              = (void*)_mmesa_read_pixels_8_8;
  708.             doDither = true;
  709.             break;
  710.         case PF_DITHER8:
  711.             ctx->Driver.WriteRGBASpan           = (void*)_mmesa_write_span_8_DITHER8;
  712.             ctx->Driver.WriteRGBSpan               = (void*)_mmesa_write_span_rgb_8_DITHER8;
  713.             ctx->Driver.WriteMonoRGBASpan       = (void*)_mmesa_write_span_mono_8_DITHER8;
  714.             ctx->Driver.WriteRGBAPixels         = (void*)_mmesa_write_pixels_8_DITHER8;
  715.             ctx->Driver.WriteMonoRGBAPixels     = (void*)_mmesa_write_pixels_mono_8_DITHER8;
  716.             ctx->Driver.ReadRGBASpan              = (void*)_mmesa_read_span_8_8;
  717.             ctx->Driver.ReadRGBAPixels              = (void*)_mmesa_read_pixels_8_8;
  718.             doDither = true;
  719.             break;
  720.         case PF_RGB555:
  721.             ctx->Driver.WriteRGBASpan           = (void*)_mmesa_write_span_16_555;
  722.             ctx->Driver.WriteRGBSpan               = (void*)_mmesa_write_span_rgb_16_555;
  723.             ctx->Driver.WriteMonoRGBASpan       = (void*)_mmesa_write_span_mono_16;
  724.             ctx->Driver.WriteRGBAPixels         = (void*)_mmesa_write_pixels_16_555;
  725.             ctx->Driver.WriteMonoRGBAPixels     = (void*)_mmesa_write_pixels_mono_16;
  726.             ctx->Driver.ReadRGBASpan              = (void*)_mmesa_read_span_16_555;
  727.             ctx->Driver.ReadRGBAPixels              = (void*)_mmesa_read_pixels_16_555;
  728.             break;
  729.         case PF_DITHER555:
  730.             ctx->Driver.WriteRGBASpan           = (void*)_mmesa_write_span_16_DITHER555;
  731.             ctx->Driver.WriteRGBSpan               = (void*)_mmesa_write_span_rgb_16_DITHER555;
  732.             ctx->Driver.WriteMonoRGBASpan       = (void*)_mmesa_write_span_mono_16_DITHER555;
  733.             ctx->Driver.WriteRGBAPixels         = (void*)_mmesa_write_pixels_16_DITHER555;
  734.             ctx->Driver.WriteMonoRGBAPixels     = (void*)_mmesa_write_pixels_mono_16_DITHER555;
  735.             ctx->Driver.ReadRGBASpan              = (void*)_mmesa_read_span_16_555;
  736.             ctx->Driver.ReadRGBAPixels              = (void*)_mmesa_read_pixels_16_555;
  737.             doDither = true;
  738.             break;
  739.         case PF_RGB565:
  740.             ctx->Driver.WriteRGBASpan           = (void*)_mmesa_write_span_16_565;
  741.             ctx->Driver.WriteRGBSpan               = (void*)_mmesa_write_span_rgb_16_565;
  742.             ctx->Driver.WriteMonoRGBASpan       = (void*)_mmesa_write_span_mono_16;
  743.             ctx->Driver.WriteRGBAPixels         = (void*)_mmesa_write_pixels_16_565;
  744.             ctx->Driver.WriteMonoRGBAPixels     = (void*)_mmesa_write_pixels_mono_16;
  745.             ctx->Driver.ReadRGBASpan              = (void*)_mmesa_read_span_16_565;
  746.             ctx->Driver.ReadRGBAPixels              = (void*)_mmesa_read_pixels_16_565;
  747.             break;
  748.         case PF_DITHER565:
  749.             ctx->Driver.WriteRGBASpan           = (void*)_mmesa_write_span_16_DITHER565;
  750.             ctx->Driver.WriteRGBSpan               = (void*)_mmesa_write_span_rgb_16_DITHER565;
  751.             ctx->Driver.WriteMonoRGBASpan       = (void*)_mmesa_write_span_mono_16_DITHER565;
  752.             ctx->Driver.WriteRGBAPixels         = (void*)_mmesa_write_pixels_16_DITHER565;
  753.             ctx->Driver.WriteMonoRGBAPixels     = (void*)_mmesa_write_pixels_mono_16_DITHER565;
  754.             ctx->Driver.ReadRGBASpan              = (void*)_mmesa_read_span_16_565;
  755.             ctx->Driver.ReadRGBAPixels              = (void*)_mmesa_read_pixels_16_565;
  756.             doDither = true;
  757.             break;
  758.         case PF_RGB888:
  759.             ctx->Driver.WriteRGBASpan           = (void*)_mmesa_write_span_24_RGB;
  760.             ctx->Driver.WriteRGBSpan               = (void*)_mmesa_write_span_rgb_24_RGB;
  761.             ctx->Driver.WriteMonoRGBASpan       = (void*)_mmesa_write_span_mono_24_RGB;
  762.             ctx->Driver.WriteRGBAPixels         = (void*)_mmesa_write_pixels_24_RGB;
  763.             ctx->Driver.WriteMonoRGBAPixels     = (void*)_mmesa_write_pixels_mono_24_RGB;
  764.             ctx->Driver.ReadRGBASpan              = (void*)_mmesa_read_span_24_RGB;
  765.             ctx->Driver.ReadRGBAPixels              = (void*)_mmesa_read_pixels_24_RGB;
  766.             break;
  767.         case PF_BGR888:
  768.             ctx->Driver.WriteRGBASpan           = (void*)_mmesa_write_span_24_BGR;
  769.             ctx->Driver.WriteRGBSpan               = (void*)_mmesa_write_span_rgb_24_BGR;
  770.             ctx->Driver.WriteMonoRGBASpan       = (void*)_mmesa_write_span_mono_24_BGR;
  771.             ctx->Driver.WriteRGBAPixels         = (void*)_mmesa_write_pixels_24_BGR;
  772.             ctx->Driver.WriteMonoRGBAPixels     = (void*)_mmesa_write_pixels_mono_24_BGR;
  773.             ctx->Driver.ReadRGBASpan              = (void*)_mmesa_read_span_24_BGR;
  774.             ctx->Driver.ReadRGBAPixels              = (void*)_mmesa_read_pixels_24_BGR;
  775.             break;
  776.         case PF_ARGB8888:
  777.             ctx->Driver.WriteRGBASpan           = (void*)_mmesa_write_span_32_ARGB;
  778.             ctx->Driver.WriteRGBSpan               = (void*)_mmesa_write_span_rgb_32_ARGB;
  779.             ctx->Driver.WriteMonoRGBASpan       = (void*)_mmesa_write_span_mono_32;
  780.             ctx->Driver.WriteRGBAPixels         = (void*)_mmesa_write_pixels_32_ARGB;
  781.             ctx->Driver.WriteMonoRGBAPixels     = (void*)_mmesa_write_pixels_mono_32;
  782.             ctx->Driver.ReadRGBASpan              = (void*)_mmesa_read_span_32_ARGB;
  783.             ctx->Driver.ReadRGBAPixels              = (void*)_mmesa_read_pixels_32_ARGB;
  784.             break;
  785.         case PF_ABGR8888:
  786.             ctx->Driver.WriteRGBASpan           = (void*)_mmesa_write_span_32_ABGR;
  787.             ctx->Driver.WriteRGBSpan               = (void*)_mmesa_write_span_rgb_32_ABGR;
  788.             ctx->Driver.WriteMonoRGBASpan       = (void*)_mmesa_write_span_mono_32;
  789.             ctx->Driver.WriteRGBAPixels         = (void*)_mmesa_write_pixels_32_ABGR;
  790.             ctx->Driver.WriteMonoRGBAPixels     = (void*)_mmesa_write_pixels_mono_32;
  791.             ctx->Driver.ReadRGBASpan              = (void*)_mmesa_read_span_32_ABGR;
  792.             ctx->Driver.ReadRGBAPixels              = (void*)_mmesa_read_pixels_32_ABGR;
  793.             break;
  794.         case PF_RGBA8888:
  795.             ctx->Driver.WriteRGBASpan           = (void*)_mmesa_write_span_32_RGBA;
  796.             ctx->Driver.WriteRGBSpan               = (void*)_mmesa_write_span_rgb_32_RGBA;
  797.             ctx->Driver.WriteMonoRGBASpan       = (void*)_mmesa_write_span_mono_32;
  798.             ctx->Driver.WriteRGBAPixels         = (void*)_mmesa_write_pixels_32_RGBA;
  799.             ctx->Driver.WriteMonoRGBAPixels     = (void*)_mmesa_write_pixels_mono_32;
  800.             ctx->Driver.ReadRGBASpan              = (void*)_mmesa_read_span_32_RGBA;
  801.             ctx->Driver.ReadRGBAPixels              = (void*)_mmesa_read_pixels_32_RGBA;
  802.             break;
  803.         case PF_BGRA8888:
  804.             ctx->Driver.WriteRGBASpan           = (void*)_mmesa_write_span_32_BGRA;
  805.             ctx->Driver.WriteRGBSpan               = (void*)_mmesa_write_span_rgb_32_BGRA;
  806.             ctx->Driver.WriteMonoRGBASpan       = (void*)_mmesa_write_span_mono_32;
  807.             ctx->Driver.WriteRGBAPixels         = (void*)_mmesa_write_pixels_32_BGRA;
  808.             ctx->Driver.WriteMonoRGBAPixels     = (void*)_mmesa_write_pixels_mono_32;
  809.             ctx->Driver.ReadRGBASpan              = (void*)_mmesa_read_span_32_BGRA;
  810.             ctx->Driver.ReadRGBAPixels              = (void*)_mmesa_read_pixels_32_BGRA;
  811.             break;
  812.         }
  813. }
  814.  
  815. /**********************************************************************/
  816. /*****               MGLMesa API Functions                        *****/
  817. /**********************************************************************/
  818.  
  819. #ifdef    __WINDOWS__
  820. ibool APIENTRY MGLMesaInitDLL(MGLCallbacks *cb,char *version)
  821. /****************************************************************************
  822. *
  823. * Function:        MGLMesaInitDLL
  824. * Parameters:    cb        - MGL callbacks structure
  825. *                version    - MGL version this DLL was built for 
  826. *
  827. * Description:    This function is called by the MGL when the MESAGL.DLL
  828. *                library is loaded under Windows. This registers a set of
  829. *                callback functions that Mesa uses to call MGL API functions
  830. *                so that we dont have to staticly link the MGL and Mesa into
  831. *                the same DLL or application.
  832. *
  833. *                We also pass back a copy of Mesa's internal global MGL
  834. *                device context which Mesa uses to directly access the MGL
  835. *                internal functions and structures. The MGL uses this pointer
  836. *                to maintain Mesa's internal structures  
  837. *
  838. *                Note that because we use the MGL's internal structures we
  839. *                also do a check to ensure that the MGL library calling us
  840. *                is the same version that we were built with.  
  841. *
  842. ****************************************************************************/
  843. {
  844.     /* Check for the correct MGL version */
  845.     if (strcmp(version,MGL_VERSION_STR) != 0)
  846.         return false;
  847.     _MGL_callbacks = *cb;
  848.     return true;
  849. }
  850. #endif
  851.  
  852. void APIENTRY MGLMesaChooseVisual(MGLDC *dc,MGLVisual *visual)
  853. /****************************************************************************
  854. *
  855. * Function:        MGLMesaChooseVisual
  856. * Parameters:    dc        - MGL device context
  857. *                visual    - Structure containing visual context information
  858. *
  859. * Description:    This function examines the visual passed to use to
  860. *                deteremine if we support the requested capabilities. If we
  861. *                don't we will modify the structure for the capabilities that
  862. *                we do support (ie: lowering the depth buffer size to 16
  863. *                bits etc).
  864. *
  865. ****************************************************************************/
  866. {
  867.     /* Force the depth buffer, stencil buffer and accum buffers to our sizes */
  868.     if (visual->depth_size)
  869.         visual->depth_size = 8 * sizeof(GLdepth);
  870.     if (visual->stencil_size)
  871.         visual->stencil_size = 8 * sizeof(GLstencil);
  872.     if (visual->accum_size)
  873.         visual->accum_size = 8 * sizeof(GLaccum);
  874.  
  875.     /* Force RGB mode for DirectColor and TrueColor modes */
  876.     if (dc->mi.bitsPerPixel > 8)
  877.         visual->rgb_flag = GL_TRUE;
  878.     if (MGL_isMemoryDC(dc))
  879.         visual->db_flag = GL_FALSE;
  880.     if (MGL_isWindowedDC(dc) || MGL_surfaceAccessType(dc) == MGL_NO_ACCESS)
  881.         visual->db_flag = GL_TRUE;
  882. }
  883.  
  884. static int countBits(uint mask)
  885. /****************************************************************************
  886. *
  887. * Function:        countBits
  888. * Parameters:    mask    - 
  889. * Returns:        number of set bits.
  890. *
  891. * Description:    Counts the number of set bits in a mask and determines the 
  892. *                shift amount.
  893. *
  894. ****************************************************************************/
  895. {
  896.     int i=0;
  897.  
  898.     if (mask) {
  899.         /* count set bits */
  900.         while ( mask & (1 << i)) {     
  901.             i++; 
  902.             };
  903.         }
  904.  
  905.     return i;
  906. }
  907.  
  908. ibool APIENTRY MGLMesaSetVisual(MGLDC *dc,MGLVisual *vis)
  909. /****************************************************************************
  910. *
  911. * Function:        MGLMesaSetVisual
  912. * Parameters:    dc        - MGL device context
  913. *                visual    - Structure containing visual context information
  914. * Returns:        True on success, false if visual creation failed
  915. *
  916. * Description:    This function attempts to create a Mesa visual for the
  917. *                device context. If this succeeds then Mesa can properly
  918. *                handle the requested visual.
  919. *
  920. ****************************************************************************/
  921. {
  922.     GLfloat red_scale, green_scale, blue_scale, alpha_scale;
  923.     GLint red_bits, green_bits, blue_bits, alpha_bits;
  924.  
  925.     /* Do quick check on incoming visual */
  926.     if (dc->mi.bitsPerPixel > 8 && !vis->rgb_flag)
  927.         return false;
  928.     if (dc->mi.bitsPerPixel < 8)
  929.         return false; 
  930.     if ((dc->mi.xRes+1 > MAX_WIDTH) || (dc->mi.yRes+1 > MAX_HEIGHT))
  931.         return false;
  932.     if (MGL_isMemoryDC(dc) && vis->db_flag)
  933.         return false;
  934.     if ((MGL_isWindowedDC(dc) || MGL_surfaceAccessType(dc) == MGL_NO_ACCESS) && !vis->db_flag)
  935.         return false;
  936.  
  937.     /* Create color channel scale factors from pixel format info */
  938.     red_scale   = (GLfloat)dc->pf.redMask;
  939.     green_scale = (GLfloat)dc->pf.greenMask;
  940.     blue_scale  = (GLfloat)dc->pf.blueMask;
  941.     alpha_scale = 255.0;
  942.  
  943.     red_bits     = countBits(dc->pf.redMask);    
  944.     green_bits     = countBits(dc->pf.greenMask);    
  945.     blue_bits     = countBits(dc->pf.blueMask);    
  946.     alpha_bits     = countBits(dc->pf.rsvdMask);
  947.  
  948.     MGL_clearCurrentDC();
  949.     dc->visual = gl_create_visual( vis->rgb_flag, 
  950.                                    vis->alpha_flag, 
  951.                                    vis->db_flag,
  952.                                    GL_FALSE,        /* stereo */
  953.                                    vis->depth_size, 
  954.                                    vis->stencil_size, 
  955.                                    vis->accum_size,
  956.                                    dc->mi.bitsPerPixel,
  957.                                    red_bits,
  958.                                    green_bits,
  959.                                    blue_bits,
  960.                                    alpha_bits);
  961.     return (dc->visual != NULL);
  962. }
  963.  
  964. ibool APIENTRY MGLMesaCreateContext(MGLDC *dc,ibool forceMemDC)
  965. /****************************************************************************
  966. *
  967. * Function:        MGLMesaCreateContext
  968. * Parameters:    dc            - MGLDC to create rendering context for
  969. *                forceMemDC    - True to force rendering to memory back buffer
  970. * Returns:        True on success, false on failure.
  971. *
  972. * Description:    Attempts to create a Mesa rendering context for the
  973. *                device context. The application programmer must first
  974. *                call MGLMesaSetVisual on the MGLDC to set the visual format
  975. *                before calling this function.
  976. *
  977. *                If we dont have hardware page flipping or the user has
  978. *                forced memory buffering with the forceMemDC function then
  979. *                we will allocate a system memory back buffer for double
  980. *                buffering. Note that if we have hardware page flipping
  981. *                and system buffering has been forced, we will still flip
  982. *                between hardware pages to eliminate all tearing. This
  983. *                option is intended mainly as a performance option for
  984. *                systems where system memory rendering is faster. 
  985. *
  986. ****************************************************************************/
  987. {
  988.     palette_t    pal[256];
  989.  
  990.     /* Ensure that the visual has been created first */
  991.     MGL_clearCurrentDC();
  992.     if (!dc->visual)
  993.         return false;
  994.  
  995.     /* Allocate memory for the rendering context structure and create it */
  996.     if ((dc->rc = (void*)calloc(1,sizeof(MGLRC))) == NULL)
  997.         goto Error;
  998.     dc->rc->dispdc = dc;
  999.     dc->rc->gl_ctx = gl_create_context(dc->visual,NULL,(void*)dc->rc, GL_TRUE);
  1000.     if (!dc->rc)
  1001.         goto Error;
  1002.  
  1003.     /* Allocate the ancillary buffers */
  1004.     if ((dc->rc->gl_buffer = gl_create_framebuffer(dc->visual)) == NULL)
  1005.         goto Error;
  1006.  
  1007.     /* Allocate back memory DC buffer if necessary */
  1008.     if ((dc->visual->DBflag && dc->mi.maxPage == 0) || forceMemDC || (MGL_surfaceAccessType(dc) == MGL_NO_ACCESS)) {
  1009.         dc->rc->memdc = MGL_createMemoryDC(dc->mi.xRes+1,dc->mi.yRes+1,dc->mi.bitsPerPixel,&dc->pf);
  1010.         if (!dc->rc->memdc)
  1011.             goto Error;
  1012.         dc->rc->dc = dc->rc->memdc;
  1013.         }
  1014.     else
  1015.         dc->rc->dc = dc->rc->dispdc;
  1016.  
  1017.     /* Initialize double buffering */
  1018.     if (dc->visual->DBflag && dc->mi.maxPage > 0) {
  1019.         MGL_setVisualPage(dc,dc->rc->frontbuffer = 0,false);
  1020.         MGL_setActivePage(dc,dc->rc->backbuffer = 1);
  1021.         }
  1022.  
  1023.     /* Initialize the private rendering context information */
  1024.     if (!dc->visual->RGBAflag) {
  1025.         dc->rc->dithered_pf = dc->rc->undithered_pf = PF_INDEX;
  1026.         MGL_getPalette(dc,pal,256,0);
  1027.         }
  1028.     else {
  1029.         if (dc->mi.bitsPerPixel > 8) {
  1030.             /* DirectColor or TrueColor display */
  1031.             if (dc->mi.bitsPerPixel == 15) {
  1032.                 dc->rc->undithered_pf = PF_RGB555;
  1033.                 dc->rc->dithered_pf = PF_DITHER555;
  1034.                 }
  1035.             else if (dc->mi.bitsPerPixel == 16) {
  1036.                 dc->rc->undithered_pf = PF_RGB565;
  1037.                 dc->rc->dithered_pf = PF_DITHER565;
  1038.                 }
  1039.             else if (dc->mi.bitsPerPixel == 24) {
  1040.                 if (dc->pf.redPos == 0)
  1041.                     dc->rc->undithered_pf = dc->rc->dithered_pf = PF_BGR888;
  1042.                 else
  1043.                     dc->rc->undithered_pf = dc->rc->dithered_pf = PF_RGB888;
  1044.                 }
  1045.             else {
  1046.                 if (dc->pf.redPos == 0)
  1047.                     dc->rc->undithered_pf = dc->rc->dithered_pf = PF_ABGR8888;
  1048.                 else if (dc->pf.redPos == 8)
  1049.                     dc->rc->undithered_pf = dc->rc->dithered_pf = PF_BGRA8888;
  1050.                 else if (dc->pf.redPos == 16)
  1051.                     dc->rc->undithered_pf = dc->rc->dithered_pf = PF_ARGB8888;
  1052.                 else
  1053.                     dc->rc->undithered_pf = dc->rc->dithered_pf = PF_RGBA8888;
  1054.                 }
  1055.             }
  1056.         else {
  1057.             /* 8bpp RGB display */
  1058.             dc->rc->undithered_pf = PF_RGB8;
  1059.             dc->rc->dithered_pf = PF_DITHER8;
  1060.             MGL_getHalfTonePalette(pal);
  1061.             }
  1062.         }
  1063.     dc->rc->gl_vis = dc->visual;
  1064.     dc->rc->bottom = dc->mi.yRes+1;
  1065.     dc->rc->pixelformat = dc->rc->dithered_pf;
  1066.     dc->rc->bufferMode = dc->visual->DBflag ? GL_BACK : GL_FRONT;
  1067.     setup_DD_pointers(dc->rc->gl_ctx);
  1068.  
  1069.     /* Setup the default palette for the device context */
  1070.     if (dc->mi.bitsPerPixel == 8) {
  1071.         MGLMesaSetPalette(dc,pal,256,0);
  1072.         MGLMesaRealizePalette(dc,256,0,false);
  1073.         }
  1074.     return true;
  1075.  
  1076. Error:
  1077.     MGLMesaDestroyContext(dc);
  1078.     return false;
  1079. }
  1080.  
  1081. void APIENTRY MGLMesaDestroyContext(MGLDC *dc)
  1082. /****************************************************************************
  1083. *
  1084. * Function:        MGLMesaDestroyContext
  1085. * Parameters:    dc    - MGLDC to destroy rendering context for
  1086. *
  1087. * Description:    Destroys the rendering context and returns the MGLDC back
  1088. *                to it's original state before 3D rendering was enabled.
  1089. *
  1090. ****************************************************************************/
  1091. {
  1092.     if (dc->rc) {
  1093.         if (dc->rc->memdc)
  1094.             MGL_destroyDC(dc->rc->memdc);
  1095.         gl_destroy_framebuffer(dc->rc->gl_buffer);
  1096.         gl_destroy_context(dc->rc->gl_ctx);
  1097.         free(dc->rc);
  1098.         }
  1099.     dc->rc = NULL;
  1100.     gl_destroy_visual(dc->visual);
  1101.     dc->visual = NULL;
  1102. }
  1103.  
  1104. void APIENTRY MGLMesaMakeCurrent(MGLDC *dc)
  1105. /****************************************************************************
  1106. *
  1107. * Function:        MGLMesaMakeCurrent
  1108. * Parameters:    dc    - MGLDC to make current
  1109. *
  1110. * Description:    Makes the passed in MGLDC the current rendering context
  1111. *                for OpenGL functions. Note that we cache a global copy
  1112. *                of this rendering context for speed (we are single threaded)
  1113. *                so we flush this back when the context is made a different
  1114. *                one.    
  1115. *
  1116. ****************************************************************************/
  1117. {
  1118.     if (dc && dc->rc == _MM_rcPtr)
  1119.         return;
  1120.     if (_MM_rcPtr) {
  1121.         *_MM_rcPtr = RC;                /* 'Write back' the old RC        */
  1122.         _MM_rcPtr = NULL;                /* This RC is no longer cached    */
  1123.         gl_make_current(NULL, NULL);
  1124.         MGL_clearCurrentDC();
  1125.         }
  1126.     if (dc) {
  1127.         gl_make_current(dc->rc->gl_ctx, dc->rc->gl_buffer);
  1128.         _MM_rcPtr = dc->rc;                /* Cache DC in global structure    */
  1129.         RC = *dc->rc;                    /* Save pointer to original DC    */
  1130.         MI = RC.dc->mi;                    /* Save cached MGL internals    */
  1131.         PF = RC.dc->pf;
  1132.         VECS = RC.dc->r;
  1133.         set_buffer(dc->rc->gl_ctx,RC.bufferMode);
  1134.         if (RC.gl_ctx->Viewport.Width == 0) {
  1135.             /* initialize viewport to window size */
  1136.             gl_Viewport(RC.gl_ctx, 0, 0, MI.xRes+1, MI.yRes+1);
  1137.             RC.gl_ctx->Scissor.Width = MI.xRes+1;
  1138.             RC.gl_ctx->Scissor.Height = MI.yRes+1;
  1139.             }
  1140.         }
  1141. }
  1142.  
  1143. void APIENTRY MGLMesaSwapBuffers(MGLDC *dc,ibool waitVRT)
  1144. /****************************************************************************
  1145. *
  1146. * Function:        MGLMesaSwapBuffers
  1147. * Parameters:    dc        - MGLDC to swap buffers for
  1148. *                waitVRT    - True to wait for vertical retrace
  1149. *
  1150. * Description:    Swaps the display buffers for the MGL device context. If
  1151. *                we have a memory DC this is blitted to the display, and
  1152. *                if we have harware page flipping we flip hardware display
  1153. *                pages.    
  1154. *
  1155. ****************************************************************************/
  1156. {
  1157.     if (!RC.gl_vis->DBflag)
  1158.         return;
  1159.     if (RC.memdc) {
  1160.         /* We have a memory buffer so blit it to the screen */
  1161.         MGL_bitBltCoord(RC.dispdc,RC.memdc,0,0,MI.xRes+1,MI.yRes+1,0,0,MGL_REPLACE_MODE);
  1162.         }
  1163.     if (RC.dc->mi.maxPage > 0) {
  1164.         /* Hardware page flipping */
  1165.         RC.frontbuffer ^= 1;
  1166.         RC.backbuffer = RC.frontbuffer ^ 1;
  1167.         if (RC.bufferMode == GL_FRONT)
  1168.             MGL_setActivePage(RC.dc,RC.frontbuffer);
  1169.         else
  1170.             MGL_setActivePage(RC.dc,RC.backbuffer);
  1171.         MGL_setVisualPage(RC.dc,RC.frontbuffer,waitVRT);
  1172.         }
  1173. }
  1174.  
  1175. void APIENTRY MGLMesaSetPaletteEntry(MGLDC *dc,int entry,uchar red,uchar green,uchar blue)
  1176. /****************************************************************************
  1177. *
  1178. * Function:        MGLMesaSetPaletteEntry
  1179. * Parameters:    dc        - MGLDC to destroy rendering context for
  1180. *                entry    - Index of entry to set
  1181. *                red,...    - Color values for palette entry
  1182. *
  1183. * Description:    Sets a single color palette entry in the device context.
  1184. *
  1185. ****************************************************************************/
  1186. {
  1187.     MGL_setPaletteEntry(dc,entry,red,green,blue);
  1188.     if (dc->rc && dc->rc->memdc)
  1189.         MGL_setPaletteEntry(dc->rc->memdc,entry,red,green,blue);
  1190. }
  1191.  
  1192. void APIENTRY MGLMesaSetPalette(MGLDC *dc,palette_t *pal,int numColors,int startIndex)
  1193. /****************************************************************************
  1194. *
  1195. * Function:        MGLMesaDestroyContext
  1196. * Parameters:    dc    - MGLDC to destroy rendering context for
  1197. *
  1198. * Description:    Destroys the rendering context and returns the MGLDC back
  1199. *                to it's original state before 3D rendering was enabled.
  1200. *
  1201. ****************************************************************************/
  1202. {
  1203.     MGL_setPalette(dc,pal,numColors,startIndex);
  1204.     if (dc->rc && dc->rc->memdc)
  1205.         MGL_setPalette(dc->rc->memdc,pal,numColors,startIndex);
  1206. }
  1207.  
  1208. void APIENTRY MGLMesaRealizePalette(MGLDC *dc,int numColors,int startIndex,int waitVRT)
  1209. /****************************************************************************
  1210. *
  1211. * Function:        MGLMesaDestroyContext
  1212. * Parameters:    dc    - MGLDC to destroy rendering context for
  1213. *
  1214. * Description:    Destroys the rendering context and returns the MGLDC back
  1215. *                to it's original state before 3D rendering was enabled.
  1216. *
  1217. ****************************************************************************/
  1218. {
  1219.     MGL_realizePalette(dc,numColors,startIndex,waitVRT);
  1220.     if (dc->rc && dc->rc->memdc)
  1221.         MGL_realizePalette(dc->rc->memdc,numColors,startIndex,waitVRT);
  1222. }
  1223.  
  1224.